package com.drool.engine.controller;

import com.drool.engine.entity.QueryParam;
import com.drool.engine.entity.RuleResult;
import com.drool.engine.listener.RuleRuntimeEventListenerImpl;
import com.drool.engine.service.RuleEngineService;
import com.drool.engine.vo.Demo;
import com.drool.engine.vo.Person;
import org.drools.decisiontable.SpreadsheetCompiler;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieModule;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieSession;
import org.kie.internal.io.ResourceFactory;
import org.kie.internal.utils.KieHelper;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

@RestController
@RequestMapping("/rule")
public class RuleController {

    @Resource
    private KieSession kieSession;
    @Resource
    private RuleEngineService ruleEngineService;


    /**
     * 普通的测试规则执行
     * @return
     */
    @RequestMapping("/hello.drl")
    public String testHelloDrl() {
        Person p = new Person();
        p.setName("kelvin");
        p.setAge(18);
        System.out.println("插入working memory的Person数据" + p.toString());
        kieSession.insert(p);
        kieSession.addEventListener(new RuleRuntimeEventListenerImpl());
        kieSession.fireAllRules();
        System.out.println("执行完规则后的Person数据" + p.toString());
        return "1";
    }

    /**
     * 加载drl字符串规则，并执行
     * @return
     */
    @RequestMapping("/dynamic/drl/string")
    public String dynamicDrlUsingString() {
        String myRule = "package rules rule \"Hello World 2\" when eval(true) then System.out.println(\"Test, Drools!\"); end";
        System.out.println(myRule);
        KieHelper helper = new KieHelper();
        helper.addContent(myRule, ResourceType.DRL);
        KieSession ksession = helper.build().newKieSession();
        int i = ksession.fireAllRules();
        System.out.println("执行了" + i+ "条规则");
        ksession.dispose();

        return "1";
    }


    /**
     * 动态规则（字符串方式）
     * 这个是通过excel 决策表来生成drl字符串，构造kiesession来执行规则
     * @return
     */
    @RequestMapping("/excel/decision/table")
    public String excelDecisionTable() {
        // 构建KieSession, 这部分写法是固定的
        String myRule = convertExcelToDrl("decisionTable.xlsx");
        KieHelper helper = new KieHelper();
        helper.addContent(myRule, ResourceType.DRL);
        KieSession ksession = helper.build().newKieSession();

        // 构建实体类对象
        Demo demo = new Demo();
        demo.setA(6);
        demo.setB(4);
        demo.setC(4);

        // 将要过规则的类传进 kieSession 中
        ksession.insert(demo);
        // 调用 fireAllRules() 方法进行规则处理，同时可以得知走了几个规则
        int count = ksession.fireAllRules();
        System.out.println("总共触发了: " + count + " 条规则");
        System.out.println(demo);

        return "1";
    }

    /**
     * 将classpath下decisionTable目录下的fileName（例如decisionTable.xlsx）转换成drl字符串
     * @param fileName
     * @return
     */
    private String convertExcelToDrl(String fileName) {
        SpreadsheetCompiler compiler = new SpreadsheetCompiler();
        // 最后一个参数是excel里 sheet 的名称
        String rules = compiler.compile(ResourceFactory.newClassPathResource("decisionTable" + File.separator + fileName, "UTF-8"), "Sheet1");
        System.out.println("转换excel到drl结果是\n" + rules);
//        try {
//            BufferedWriter out = new BufferedWriter(new FileWriter("src/main/resources/rules/test-rule-excel.drl"));
//            out.write(rules);
//            out.close();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
        return rules;
    }

    @RequestMapping("/param")
    public void param() {
        QueryParam queryParam1 = new QueryParam();
        queryParam1.setParamId("1");
        queryParam1.setParamSign("+");
        QueryParam queryParam2 = new QueryParam();
        queryParam2.setParamId("2");
        queryParam2.setParamSign("-");
        // 入参
        kieSession.insert(queryParam1);
        kieSession.insert(queryParam2);
        kieSession.insert(this.ruleEngineService);

        // 返参
        RuleResult resultParam = new RuleResult();
        kieSession.insert(resultParam);
        kieSession.fireAllRules();
    }


}
